package com.api.util.repo;

import java.util.HashMap;
import java.util.Map;

public class DtoAccessor {

	private final DtoRepository dtoRepository;

	private final Map<Class<?>, DtoFactory<?>> factories;

	public DtoAccessor(DtoRepository dtoRepository, Map<Class<?>, DtoFactory<?>> factories) {
		this.dtoRepository = dtoRepository;
		this.factories = factories;
	}

	public DtoAccessor(DtoRepository dtoRepository) {
		this(dtoRepository, new HashMap<Class<?>, DtoFactory<?>>());
	}

	public <T> void registerFactory(Class<T> dtoClass, DtoFactory<T> dtoFactory) {
		this.factories.put(dtoClass, dtoFactory);
	}

	public <T> T getDto(String name, Class<T> dtoClass) {
		if (!factories.containsKey(dtoClass) && !dtoRepository.existsDto(name, dtoClass)) {
			throw new IllegalStateException(String.format("There isn't a dtoFactory registered for class '%s'", dtoClass));
		}
		@SuppressWarnings("unchecked")
		DtoFactory<T> factory = (DtoFactory<T>) factories.get(dtoClass);
		return getDto(name, dtoClass, factory);
	}

	public <T> T getDto(String name, Class<T> dtoClass, DtoFactory<T> dtoFactory) {
		T dto = null;
		if (dtoRepository.existsDto(name, dtoClass)) {
			dto = dtoRepository.getDto(name, dtoClass);
		} else {
			dto = dtoFactory.createDto(name);
			dtoRepository.saveDto(name, dto);
		}
		return dto;
	}
}
